﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UtilZ.Dotnet.Ex.Communication.Base;

namespace UtilZ.Dotnet.Ex.Communication.Ports
{
    /// <summary>
    /// 串口信息客户端初始化参数
    /// </summary>
    public class SerialPortClientInitPara : ClientInitParaAbs
    {
        /// <summary>
        /// 要使用的端口（例如 COM1）
        /// </summary>
        public string PortName { get; private set; }

        /// <summary>
        /// 波特率
        /// </summary>
        public int BaudRate { get; private set; }

        /// <summary>
        /// 指定 System.IO.Ports.SerialPort 对象的奇偶校验位,
        /// System.IO.Ports.SerialPort.Parity 值之一
        /// </summary>
        public SerialPortParity Parity { get; private set; }

        /// <summary>
        /// 数据位值
        /// </summary>
        public int DataBits { get; private set; }

        /// <summary>
        /// 指定在 System.IO.Ports.SerialPort 对象上使用的停止位的数目,
        /// System.IO.Ports.SerialPort.StopBits 值之一
        /// </summary>
        public SerialPortStopBits StopBits { get; private set; }

        private int _receiveDataSize = 4096;
        /// <summary>
        /// 接收数据缓存大小
        /// </summary>
        public int ReceiveBufferSize
        {
            get { return _receiveDataSize; }
            set
            {
                if (value <= 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(value), "单次接收数据包不能小于等于0");
                }

                _receiveDataSize = value;
            }
        }

        private int _sendBufferSize = 2048;
        /// <summary>
        /// 发送数据缓存大小
        /// </summary>
        public int SendBufferSize
        {
            get { return _sendBufferSize; }
            set
            {
                if (value <= 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(value), "发送缓存不能小于等于0");
                }

                _sendBufferSize = value;
            }
        }

        /// <summary>
        /// 串口数据发送最小间隔,单位:100纳秒.小于等于0无间隔
        /// </summary>
        public int SendInterval100NS { get; set; } = 0;


        private int _asynOpenIntervalMilliseconds = 1000;
        /// <summary>
        /// 异步建立串口通信连接间隔，当值小于等于0时,采用默认值1000
        /// </summary>
        public int AsynOpenIntervalMilliseconds
        {
            get { return _asynOpenIntervalMilliseconds; }
            set { _asynOpenIntervalMilliseconds = value; }
        }

        /// <summary>
        /// 获取异步建立串口通信连接间隔
        /// </summary>
        /// <returns>异步建立串口通信连接间隔</returns>
        public int GetAsynOpenIntervalMilliseconds()
        {
            var asynOpenIntervalMilliseconds = this._asynOpenIntervalMilliseconds;
            if (asynOpenIntervalMilliseconds <= 0)
            {
                asynOpenIntervalMilliseconds = 1000;
            }
            return asynOpenIntervalMilliseconds;
        }

        /// <summary>
        /// 接收数据超时时长,默认根据波特率计算发送/接收字符间隔，再放大100倍作为接收数据超时时长
        /// </summary>
        public TimeSpan RecieveDataTimeout { get; set; }

        /// <summary>
        /// 接收数据空间时等待间隔
        /// </summary>
        public TimeSpan RecieveDataIdleWaitInterval { get; set; }




        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="unpacker">分包器</param>
        /// <param name="portName">要使用的端口（例如 COM1）</param>
        /// <param name="baudRate">波特率</param>
        /// <param name="parity">System.IO.Ports.SerialPort.Parity 值之一</param>
        /// <param name="dataBits">数据位值</param>
        /// <param name="stopBits">System.IO.Ports.SerialPort.StopBits 值之一</param>
        public SerialPortClientInitPara(IUnpacker unpacker, string portName, int baudRate, SerialPortParity parity, int dataBits, SerialPortStopBits stopBits)
            : base(unpacker)
        {
            if (string.IsNullOrWhiteSpace(portName))
            {
                throw new ArgumentNullException(nameof(portName));
            }

            this.PortName = portName;
            this.BaudRate = baudRate;
            this.Parity = parity;
            this.DataBits = dataBits;
            this.StopBits = stopBits;

            //根据波特率计算发送/接收字符间隔，再放大100倍作为接收数据超时时长
            double millisecondsTimeout = 1000d / baudRate * 100;
            this.RecieveDataTimeout = TimeSpan.FromMilliseconds(millisecondsTimeout);
            this.RecieveDataIdleWaitInterval = TimeSpan.FromMilliseconds(1000 * 60);
        }
    }
}
